package com.wrt.sps.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;

import lombok.extern.log4j.Log4j2;

/**
 * 媒体工具类
 * 
 * @author 文瑞涛
 * @date 2021年1月12日 上午10:13:41
 */
@Log4j2
public class MediaUtils {

	private MediaUtils() {}
	
	/**
	 * 缓存文件头信息-文件头信息
	 */
	private static final HashMap<String, String> FILE_HEAD_INFO = new HashMap<>();
	static {
		// images
		FILE_HEAD_INFO.put("jpg", "FFD8FF");
		FILE_HEAD_INFO.put("jpeg", "FFD8FF");
		FILE_HEAD_INFO.put("png", "89504E47");
	}
	/**
	 * 判断文件格式是否正确
	 * 
	 * @param fileInputStream 文件输入流
	 * @param extension       文件名称（带有后缀名）
	 * @param formats         文件格式范围（可选参数）
	 * 
	 * @return true-格式正确; false-输入流为空; false-文件格式名称为空;false-格式不匹配或格式未在系统内定义
	 */
	public static boolean judgeFileFormatCorrect(InputStream fileInputStream, String extension, String... formats){
		boolean result = false;
		if (null == fileInputStream || null == extension || extension.length() <= 0) {
			return result;
		}
		boolean hasFormatScope = null != formats && formats.length > 0;
		String systemHead = FILE_HEAD_INFO.get(extension);
		if (null == systemHead) {
			return false;
		}
		try {
			String fileHead = getFileHeader(fileInputStream);
			if(null != fileHead) {
				result = fileHead.startsWith(systemHead);
				if (hasFormatScope) {
					result = result && fileFormatInScope(extension, formats);
				}
			}
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return result;
	}
	
	/**
	 * 判断文件格式是否处于待判断范围内
	 * 
	 * @param extension 文件格式
	 * @param formats   文件格式范围
	 * 
	 * @return true-处于范围内；false-不在范围内
	 */
	private static boolean fileFormatInScope(String extension, String... formats) {
		boolean result = false;
		for (String format : formats) {
			if (extension.equalsIgnoreCase(format)) {
				result = true;
				break;
			}
		}
		return result;
	}
	
	/**
	 * 根据文件输入流获取文件头信息
	 * 
	 * @param fileInputStream 文件输入流
	 * 
	 * @return 文件头信息
	 * @throws IOException
	 */
	private static String getFileHeader(InputStream fileInputStream) throws IOException {
		String value = null;
		byte[] b = new byte[4];
		fileInputStream.read(b, 0, b.length);
		value = bytesToHexString(b);
		return value;
	}
	
	/**
	 * 将要读取文件头信息的文件的byte数组转换成String类型表示
	 * 
	 * @param src 要读取文件头信息的文件的byte数组
	 * 
	 * @return 文件头信息
	 */
	private static String bytesToHexString(byte[] src) {
		StringBuilder builder = new StringBuilder();
		if (src == null || src.length <= 0) {
			return null;
		}
		String hv;
		for (int i = 0; i < src.length; i++) {
			// 以十六进制（基数 16）无符号整数形式返回一个整数参数的字符串表示形式，并转换为大写
			hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
			if (hv.length() < 2) {
				builder.append(0);
			}
			builder.append(hv);
		}
		return builder.toString();
	}
}
